package com.huaxin.common.message.mp3recorder.audio.sender;

import android.media.AudioRecord;
import android.util.Log;

import com.huaxin.common.message.mp3recorder.audio.AudioCodec;
import com.huaxin.common.message.mp3recorder.audio.AudioConfig;
import com.huaxin.common.message.mp3recorder.audio.NetConfig;
import com.huaxin.common.message.netnat.NetNatConfig;

import java.io.IOException;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.InetAddress;

public class AudioRecorder implements Runnable {

    String LOG = "Recorder ";

    public static boolean changed = true;
    private boolean isRecording = false;
    private AudioRecord audioRecord;

    private int audioBufSize = 0;

    //
    private short[] samples;// data
    // samples size
    private int bufferSize = 0;

    DatagramSocket socket;
    DatagramPacket packet;
    byte[] buffer;

    /*
     * start recording
     */
    public void startRecording() {
        if (samples == null) {
            bufferSize = AudioConfig.BUFFER_FRAME_SIZE;

            audioBufSize = AudioRecord.getMinBufferSize(AudioConfig.SAMPLERATE,
                    AudioConfig.RECORDER_CHANNEL_CONFIG, AudioConfig.AUDIO_FORMAT);
            if (audioBufSize == AudioRecord.ERROR_BAD_VALUE) {
                Log.e(LOG, "audioBufSize error");
                return;
            }

            samples = new short[audioBufSize];
            buffer = new byte[bufferSize];
        }

        if (socket == null) {
            try {
                socket = new DatagramSocket();
                packet = new DatagramPacket(buffer, 0, InetAddress.getByName(NetConfig.SERVER_HOST), NetConfig.SERVER_PORT);
            } catch (Exception e) {
                Log.e(LOG, "DatagramSocket or DatagramPacket error");
                e.printStackTrace();
                return;
            }
        }

        new Thread(this).start();
    }

    /*
     * stop
     */
    public void stopRecording() {
        this.isRecording = false;
    }

    public boolean isRecording() {
        return isRecording;
    }

    public void run() {
        System.out.println(LOG + "audioRecord startRecording()");
        android.os.Process
                .setThreadPriority(android.os.Process.THREAD_PRIORITY_URGENT_AUDIO);
        this.isRecording = true;

        // the size of audio read from recorder & encode from speex
        int num = 0;
        int seqn = 0;

        boolean test = true;

        AudioCodec.initCodec(30);

        while (isRecording) {
            // 初始化recorder
            if (changed || null == audioRecord) {
                if (audioRecord != null) {
                    audioRecord.stop();
                    audioRecord.release();
                }
                changed = false;
                audioRecord = new AudioRecord(AudioConfig.AUDIO_RESOURCE,
                        AudioConfig.SAMPLERATE,
                        AudioConfig.RECORDER_CHANNEL_CONFIG,
                        AudioConfig.AUDIO_FORMAT, audioBufSize);
                if (audioRecord.getState() != AudioRecord.STATE_INITIALIZED) {
                    audioRecord = null;
                    Log.d("hebing", "init audio record failed!");
                    break;
                }
                audioRecord.startRecording();
            }
            //从 audioRecord 读取一帧音频数据(50帧/s)
            num = audioRecord.read(samples, 0, bufferSize);
            if (num > 0) {
                num = AudioCodec.encode(samples, 0, buffer, num);
                if (test) {
                    byte[] send = new byte[num];
                    for (int i = 0; i < num; i++) {
                        send[i] = buffer[num];
                    }
                    packet.setData(send, 0, send.length);
                } else {
                    byte[] send = new byte[num + 10];
                    /**
                     * VOICE_DATA
                     * 客户端处理(6 + 1 + 2 + 1)
                     * 普通的音频数据包
                     * 格式如下
                     * MAGIC
                     * + VOICE_DATA
                     * + 序列号 (Int行，从1开始累积叠加，达到65535后重置为1)
                     * + 转发数据长度
                     * + 转发数据
                     */
                    for (int i = 0; i < NetNatConfig.MAGIC.length; i++) {
                        send[i] = NetNatConfig.MAGIC[i];
                    }
                    send[6] = NetNatConfig.Type.VOICE_DATA;
                    NetNatConfig.setInt(seqn++, send, 7, 9);
                    send[9] = (byte) (num & 0xFF);
                    for (int i = 0; i < num; i++) {
                        send[10 + i] = buffer[num];
                    }
                    packet.setData(send, 0, send.length);
                }
                try {
                    socket.send(packet);
                } catch (IOException e) {
//                    e.printStackTrace();
                }
            }
            try {
                Thread.sleep(10);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
        System.out.println(LOG + "end recording");
        audioRecord.stop();
        audioRecord.release();
        audioRecord = null;
    }
}
